package com.example.spring.framework.aop;

import com.example.spring.framework.aop.intercept.MethodInvocation;
import com.example.spring.framework.aop.support.AdvisedSupport;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

/**
 * @Classname JdkDynamicAopProxy
 * @Date 2019/4/22 23:34
 * @Author admin
 * @Description TODO
 */
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {

    private AdvisedSupport advisedSupport;

    public JdkDynamicAopProxy(AdvisedSupport advisedSupport) {
        this.advisedSupport = advisedSupport;
    }

    @Override
    public Object getProxy() {
        return getProxy(this.advisedSupport.getTargetClass().getClassLoader());
    }

    @Override
    public Object getProxy(ClassLoader classLoader) {
        return Proxy.newProxyInstance(classLoader, this.advisedSupport.getTargetClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        List<Object> intercepterAndDynamicMethodMatchers = this.advisedSupport.getInterceptorsAndDynamicInterceptionAdvice(method, this.advisedSupport.getTargetClass());
        MethodInvocation invocation = new MethodInvocation(proxy, this.advisedSupport.getTargetObject(), method, args, this.advisedSupport.getTargetClass(), intercepterAndDynamicMethodMatchers);
        return invocation.procccd();
    }
}
